package 线程通信;

public class Test {
    public static void main(String[] args) {
        // 什么是线程通信
        // 当多个线程共同操作共享的资源时, 线程间通过某种方式互相告知自己的状况, 以相互协调, 并避免无效的资源争夺

        // 线程通信的常见模型(生产者与消费者模型)
        // 1. 生产者线程负责生产数据
        // 2. 消费者线程负责小非生产者生产的数据
        // 注意: 生产者生产完数据应该等待自己, 通知消费者消费, 消费者消费完数据也应该等待自己, 在通知生产者生产!

        // 其中Object类提供了等待和唤醒的方法
        // 1. void wait(): 让当前线程等待并释放所占锁, 直到另一个线程调用notify()方法或 notifyAll()方法
        // 2. void notify(): 唤醒正在等待的单个线程
        // 3. void notifyAll(): 唤醒正在等待的所有线程
        // 注意: 上述方法应该使用当前同步锁对象进行调用(就是当前占用锁的那个对象)


        // 需求: 三个生产者线程, 负责生产包子, 每个线程每次只能生产一个包子放在桌上
        //      两个消费者线程负责吃包子, 每人每次只能从桌上拿一个包子吃
        Desk desk = new Desk();

        // 创建三个生产者线程(三个厨师)
        new Thread(() -> {
            while (true) {
                desk.put();
            }
        },"一号厨子").start();// 一号厨子
        new Thread(() -> {
            while (true) {
                desk.put();
            }
        },"二号厨子").start();// 二号厨子
        new Thread(() -> {
            while (true) {
                desk.put();
            }
        },"三号厨子").start();// 三号厨子

        // 创建两个消费者线程(两个吃货)
        new Thread(() -> {
            while (true) {
                desk.get();
            }
        },"一号吃货").start(); //一号吃货
        new Thread(() -> {
            while (true) {
                desk.get();
            }
        },"二号吃货").start(); // 二号吃货


    }
}
